import sys
import os
from datetime import date, datetime
sys.path.append(os.path.dirname(os.path.dirname(__file__)))

from tqsdk import TqApi, TqAuth, TqSim, TqBacktest, BacktestFinished
from strategies.multi_signal_strategy import MultiSignalStrategy
from utils.config_manager import ConfigManager
from utils.strategy_recorder import StrategyDBRecorder

# 使用项目根目录的.settings
project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
config = ConfigManager(config_dir=os.path.join(project_root, '.settings'))
account_config = config.get_account_config('tqsdk_account')

# 初始化数据库记录器
db_recorder = StrategyDBRecorder(db_path="trading_backtest.db")

# 回测参数
start_date = date(2023, 1, 1)
end_date = date(2025, 11, 10)
init_balance = 10000000
start_time = datetime.now()

symbol_info = {
    "IF": {
        "exchange": "CFFEX",
        # RSRS 参数
        "rsrs_period": 18,
        "rsrs_std_period": 600,
        # OC 参数
        "oc_score_period": 20,
        "oc_std_period": 600,
        # 其他参数
        "long_threshold": 0.7,
        "short_threshold": -0.7,
    }
}

sim = TqSim(init_balance=init_balance)
api = TqApi(
    account=sim,
    backtest=TqBacktest(start_dt=start_date, end_dt=end_date),
    auth=TqAuth(account_config['user_id'], account_config['password']),
    web_gui="http://127.0.0.1:2017"
)

strategy = MultiSignalStrategy(api, symbol_info, market_period=24*60)  # 日线

try:
    strategy.on_bar()
except BacktestFinished:
    end_time = datetime.now()
    run_duration = (end_time - start_time).total_seconds()
    
    # 获取账户信息和统计数据
    account = api.get_account()
    tqsdk_stats = getattr(account, '_tqsdk_stat', None)
    trade_log = getattr(sim, 'trade_log', None)
    
    # 打印回测结果
    print(f"\n{'='*60}")
    print(f"多信号策略回测结果")
    print(f"{'='*60}")
    print(f"初始资金: {init_balance:,.0f}")
    print(f"最终资金: {account.balance:,.0f}")
    print(f"收益率: {(account.balance - init_balance) / init_balance:.2%}")
    print(f"运行时长: {run_duration:.2f} 秒")
    print(f"{'='*60}")
    
    # 保存回测结果到数据库
    try:
        import numpy as np
        serializable_params = {}
        for sym, params in symbol_info.items():
            serializable_params[sym] = {}
            for k, v in params.items():
                if isinstance(v, np.ndarray):
                    serializable_params[sym][k] = v.tolist()
                else:
                    serializable_params[sym][k] = v
        
        backtest_id = db_recorder.save_backtest_result(
            strategy_name=strategy.strategy_name,
            symbol=",".join(symbol_info.keys()),
            start_date=start_date.strftime('%Y-%m-%d'),
            end_date=end_date.strftime('%Y-%m-%d'),
            init_balance=init_balance,
            final_balance=account.balance,
            tqsdk_stats=tqsdk_stats,
            run_duration=run_duration,
            strategy_params=serializable_params,
            test_timestamp=datetime.now().isoformat()
        )
    except Exception as e:
        print(f"保存回测结果到数据库时出错: {e}")
        import traceback
        traceback.print_exc()
        backtest_id = None
    
    # 保存交易日志到数据库
    trade_count = 0
    if backtest_id and trade_log:
        try:
            trade_count = db_recorder.save_trade_logs(backtest_id, trade_log)
            print(f"已保存 {trade_count} 条交易记录到数据库")
        except Exception as e:
            print(f"保存交易日志时出错: {e}")
    
    if backtest_id:
        print(f"回测结果已保存到数据库，ID: {backtest_id}")
    else:
        print("回测结果未能保存到数据库")
    
    # 关闭 API 连接
    api.close()
    print("\n回测程序已结束")
